package com.xbongbong.paas.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.constant.TimeConstant;
import com.xbongbong.paas.pojo.dto.ReportTargetListDTO;
import com.xbongbong.paas.pojo.vo.ReportTargetListVO;
import com.xbongbong.paas.service.CompanyService;
import com.xbongbong.paas.service.TargetLogService;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.helper.ReflectHelper;
import com.xbongbong.paas.toolbox.util.DateUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.pro.constant.I18nStringConstant;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.saas.enums.CompanyConfigEnum;
import com.xbongbong.saas.enums.ReportTargetEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.toolbox.help.BasicHelper;
import com.xbongbong.sys.domain.entity.CompanyConfigEntity;
import com.xbongbong.sys.domain.entity.TargetLogEntity;
import com.xbongbong.sys.model.CompanyConfigModel;
import com.xbongbong.sys.model.TargetLogModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * Description:
 *
 * @author 李杰
 * @version v1.0
 * @date 2019/2/19 15:59
 * @since v1.0
 */
@Service("targetLogService")
public class TargetLogServiceImpl implements TargetLogService {

    private static final Logger LOG = LoggerFactory.getLogger(TargetLogServiceImpl.class);

    @Resource
    private CompanyService companyService;
    @Resource
    private CompanyConfigModel companyConfigModel;
    @Resource
    private TargetLogModel targetLogModel;

    /**
     * 简报列表
     *
     * @param reportTargetListDTO
     * @return
     */
    @Override
    public ReportTargetListVO reportList(ReportTargetListDTO reportTargetListDTO) throws XbbException {
        ReportTargetListVO reportTargetListVO = new ReportTargetListVO();
        String corpid = reportTargetListDTO.getCorpid();
        String userId = reportTargetListDTO.getUserId();
        Integer startTime = reportTargetListDTO.getStartTime();
        Integer endTime = reportTargetListDTO.getEndTime();
        try {
            //从配置表获取
            CompanyConfigEntity config = companyConfigModel.getConfigEntity(corpid, CompanyConfigEnum.REPORT_TARGETSET.getAlias());
            String configValue = (config == null) ? "" : config.getConfigValue();
            //只传了end，或者只传了start
            boolean flag = (startTime == null && endTime != null) || (startTime != null && endTime == null);
            if (flag) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100015.getMsg());
            }
            //都没传
            if (startTime == null) {
                Integer timeType = BasicHelper.getTimeType(DateUtil.getInt());
                Map<String, Integer> ret = BasicHelper.getDayStartAndEnd4Report(timeType);
                startTime = ret.get("start");
                endTime = ret.get("end");
            }
            //当天0点
            startTime = DateUtil.getTodayInt(startTime);
            //当天0点
            endTime = DateUtil.getTodayInt(endTime);
            //非周报，非月报
            flag = startTime >= endTime || (endTime - startTime != TimeConstant.SECONDS_PER_DAY && endTime - startTime != TimeConstant.SECONDS_PER_WEEK);
            if (flag) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100015.getMsg());
            }

            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put("corpid", corpid);
            param.put("userId", userId);
            param.put("del", 0);
            param.put("startTime", startTime);
            param.put("endTime", endTime);
            param.put("start", 0);
            param.put("pageNum", 1);
            List<TargetLogEntity> logList = targetLogModel.findEntitys(param);
            TargetLogEntity targetLogEntity = null;
            if (logList != null && logList.size() > 0) {
                targetLogEntity = logList.get(0);
            }
            List<JSONObject> enableTargetList = getEnableEnumAccordingModule(configValue, targetLogEntity, startTime, endTime);
            reportTargetListVO.setList(enableTargetList);
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("获取简报出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return reportTargetListVO;
    }

    /**
     * 通过CompanyConfig表的configValue值来获取【启用的】指标枚举：按照模块归类
     *
     * @param configValue     配置表配置数据
     * @param targetLogEntity 统计指标记录实体
     * @param dayStartTime    统计日/周开始时间
     * @param dayEndTime      统计日/周结束时间
     * @return
     * @version
     * @author cp.zhang
     * 创建时间：2017-8-14 下午4:16:58
     * 修改时间：
     * @since 3.11
     */
    private List<JSONObject> getEnableEnumAccordingModule(String configValue, TargetLogEntity targetLogEntity, Integer dayStartTime, Integer dayEndTime) {
        /**
         * 注，计算指标一般都是在凌晨对上一天的数据进行统计，固对于统计日（或周）的开始截至时间即上一天的开始截止
         * （1）正常情况，当天早上统计昨日数据，时间范围：dayStart--dayEnd				同时统计dayEnd-86400所在月份的数据
         * （2）今日是周一的时候，统计上一周的数据，时间范围：weekStart--weekEnd			同时统计weekEnd-96400所在月份的数据
         */
        //得到几月几日，例 08-14
        String monthDay = DateUtil.getString(dayStartTime, DateUtil.SDFMonthDay);
        String month = StringUtil.toInt(DateUtil.getMonth(dayEndTime - TimeConstant.SECONDS_PER_DAY)) + I18nMessageUtil.getMessage(I18nStringConstant.MONTH_TOTAL);
        //周报
        if (dayEndTime - dayStartTime > TimeConstant.SECONDS_PER_DAY) {
            monthDay = XbbRefTypeEnum.WORKREPORT_WEEKLY.getName() + "(" + monthDay + "~" + DateUtil.getString(dayEndTime - TimeConstant.SECONDS_PER_DAY, DateUtil.SDFMonthDay) + ")";
        }

        //模块id--模块内所有指标
        Map<Integer, List<JSONObject>> belongObjMap = new LinkedHashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        for (ReportTargetEnum cache : ReportTargetEnum.values()) {
            int code = cache.getCode();
            //configValue为空，说明公司未设置，则默认启用全部（非vip排除进销存）
            if (StringUtil.isEmpty(configValue) || configValue.contains("|" + code + "|")) {
                String name = cache.getName();
                Integer belong = cache.getBelong();
                String alias = cache.getAlias();
                Integer type = cache.getType();
                String unit = cache.getUnit();
                JSONObject object = new JSONObject();
                //简报指标名称
                object.put("name", name + "/" + unit);

                //得到的格式为：{“day”:0,”month”:0}
                String attr = (String) ReflectHelper.valueGet(targetLogEntity, alias);
                if (StringUtil.isEmpty(attr)) {
                    object.put("day", 0);
                    object.put("month", 0);
                } else {
                    JSONObject targetObject = JSONObject.parseObject(attr);
                    if (type == 1) {
                        Double amountD = targetObject.getDouble("day");
                        Double amountM = targetObject.getDouble("month");
                        //金额格式处理
                        object.put("day", StringUtil.formatDouble(amountD, 2, 1));
                        object.put("month", StringUtil.formatDouble(amountM, 2, 1));
                    } else {
                        object.put("day", targetObject.get("day"));
                        object.put("month", targetObject.get("month"));
                    }
                }

                List<JSONObject> targetList = belongObjMap.get(belong);
                if (targetList == null) {
                    targetList = new ArrayList<>();
                }
                targetList.add(object);
                belongObjMap.put(belong, targetList);
            }
        }
        List<JSONObject> enableTargetList = new ArrayList<>();
        for (Map.Entry<Integer, List<JSONObject>> entry : belongObjMap.entrySet()) {
            String belongName = ReportTargetEnum.getBelongName(entry.getKey());
            JSONObject object = new JSONObject(true);
            object.put("dayTitle", monthDay);
            object.put("monthTitle", month);
            object.put("name", belongName);
            object.put("list", entry.getValue());
            enableTargetList.add(object);
        }
        return enableTargetList;
    }
}
